<template>
  <div
    class="bg-lightColor user-con p-3 h-full rounded"
    id="user-con"
    style="
      position: relative;
      width: 100%;
      border: 1px solid rgba(128, 128, 128, 0.2);
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
      transform: translate(0);
    "
  >
    <!-- 用于小屏显示左侧部门列表的浮动折叠按钮 -->
    <n-float-button
      v-if="isSmall"
      :left="0"
      :top="0"
      shape="square"
      size="small"
      :width="30"
      :height="30"
      class="z-40 !bg-opacity-50 bg-primaryColor"
      @click="handleShowMask"
    >
      <SvgIcon icon="zhedie2" color="#fff"></SvgIcon>
    </n-float-button>
    <!-- 小屏的左侧抽屉：存放部门选择器 -->
    <n-drawer
      v-model:show="showLeftMask"
      :width="'40%'"
      :trap-focus="false"
      :block-scroll="false"
      placement="left"
      to="#user-con"
    >
      <n-drawer-content>
        <n-space vertical :size="12" align="stretch" class="pr-2">
          <n-input
            v-model:value="depNameSearch"
            placeholder="部门关键字搜索"
            size="small"
            :maxlength="25"
          >
            <template #suffix>
              <SvgIcon icon="sousuo"></SvgIcon>
            </template>
          </n-input>
          <n-tree
            :draggable="true"
            :allow-drop="handleAllowDrop"
            block-line
            :data="options"
            :override-default-node-click-behavior="override"
            :on-load="handleLoad"
            :pattern="depNameSearch"
            :show-irrelevant-nodes="true"
            :render-label="renderLabel"
            :node-props="nodeProps"
            @drop="handleDrop"
          />
          <n-dropdown
            size="small"
            trigger="manual"
            placement="bottom-start"
            :show="depDropDown.showDropdown"
            :options="depDropDown.options"
            :x="depDropDown.x"
            :y="depDropDown.y"
            @select="handleDepDropSelect"
            @clickoutside="handleDepClickoutside"
            :render-label="renderAllActionsLabel"
          />
        </n-space>
      </n-drawer-content>
    </n-drawer>

    <!-- 分割左侧部门和用户面板 -->
    <n-split
      direction="horizontal"
      style="height: 100%"
      :size="isSmall ? 0 : settingStore.depSplitSize"
      @update:size="hanldeSplitSizeChange"
      :max="isSmall ? 1 : 0.85"
      :min="isSmall ? 0 : 0.15"
      :resize-trigger-size="isSmall ? 0 : 3"
    >
      <template #1>
        <n-space
          vertical
          :size="12"
          align="stretch"
          class="pr-2"
          v-if="!isSmall"
        >
          <n-input
            v-model:value="depNameSearch"
            placeholder="部门关键字搜索"
            size="small"
            :maxlength="25"
          >
            <template #suffix> <SvgIcon icon="sousuo"></SvgIcon> </template>
          </n-input>
          <n-tree
            :draggable="true"
            :allow-drop="handleAllowDrop"
            block-line
            :data="options"
            :override-default-node-click-behavior="override"
            :on-load="handleLoad"
            :pattern="depNameSearch"
            :show-irrelevant-nodes="true"
            :render-label="renderLabel"
            :node-props="nodeProps"
            @drop="handleDrop"
          />
          <n-dropdown
            size="small"
            trigger="manual"
            placement="bottom-start"
            :show="depDropDown.showDropdown"
            :options="depDropDown.options"
            :x="depDropDown.x"
            :y="depDropDown.y"
            @select="handleDepDropSelect"
            @clickoutside="handleDepClickoutside"
            :render-label="renderAllActionsLabel"
          />
        </n-space>
      </template>
      <template #2>
        <div class="info pl-2">
          <div class="header flex items-center justify-between mb-2">
            <div class="left flex items-center">
              <n-button
                type="primary"
                text
                class="decoration-blue-500 underline text-[20px]"
                @click="handleToModifyDep"
              >
                {{ curDep?.name || '全部部门' }}
              </n-button>

              <n-popover
                trigger="hover"
                placement="right-start"
                :raw="true"
                :show-arrow="false"
              >
                <template #trigger>
                  <n-button
                    v-permission="[PERMISSIONS.DEP_EDIT]"
                    color="#e9f3f9"
                    size="small"
                    class="ml-2"
                    @click="handleToAddDep"
                  >
                    <SvgIcon
                      icon="zengjiatianjiajiahao"
                      color="#698ebf"
                    ></SvgIcon>
                  </n-button>
                </template>
                <div class="bg-yellow-100 p-2 text-[13px]">添加部门</div>
              </n-popover>

              <n-popover
                v-if="curDep && curDep.id !== '1'"
                trigger="hover"
                placement="right-start"
                :raw="true"
                :show-arrow="false"
              >
                <template #trigger>
                  <n-button
                    class="ml-2"
                    size="small"
                    color="#e9f3f9"
                    @click="handleEnterFolder"
                  >
                    <SvgIcon icon="wenjianjia1" color="#698ebf"></SvgIcon>
                  </n-button>
                </template>
                <div class="bg-yellow-100 p-2 text-[13px]">进入目录</div>
              </n-popover>

              <div
                class="size w-[120px] flex items-center ml-2 bg-[#f6f6f6] flex-col text-[13px] justify-center p-2"
              >
                <n-progress
                  type="line"
                  :percentage="
                    curDep.sizeUse && curDep.sizeMax
                      ? curDep.sizeUse / curDep.sizeMax
                      : 0
                  "
                  :show-indicator="false"
                  :stroke-width="1"
                />
                {{
                  +curDep.sizeUse ? convertFromBytes(curDep?.sizeUse) : '0B'
                }}/{{
                  +curDep.sizeMax ? convertFromBytes(curDep.sizeMax) : '无限制'
                }}
              </div>
            </div>
            <div class="right">
              <n-input
                v-model:value="userNameSerach"
                placeholder="用户关键字搜索"
                size="small"
                :maxlength="25"
                @keyup="handleKeyUp"
              >
                <template #suffix>
                  <SvgIcon
                    icon="sousuo"
                    class="cursor-pointer"
                    @click="loadUsers"
                  ></SvgIcon>
                </template>
              </n-input>
            </div>
          </div>
          <n-space
            size="large"
            class="mb-2"
            v-permission="[PERMISSIONS.USER_EDIT]"
          >
            <n-button-group size="small">
              <n-button
                type="tertiary"
                @click="handleToAddUser"
                class="text-[13px]"
              >
                新建用户
              </n-button>
              <n-dropdown
                trigger="click"
                :options="userActions"
                @select="handleBuckSelect"
              >
                <n-button type="tertiary">
                  <SvgIcon icon="xiala1" size="13px"></SvgIcon>
                </n-button>
              </n-dropdown>
            </n-button-group>
            <n-dropdown
              trigger="click"
              :options="allActions"
              :render-label="renderAllActionsLabel"
              @select="handleAllBuckSelect"
            >
              <n-button type="tertiary" size="small" class="text-[13px]">
                批量操作
                <SvgIcon icon="xiala1" size="13px" class="ml-1"></SvgIcon
              ></n-button>
            </n-dropdown>
            <n-button-group size="small">
              <n-button
                type="tertiary"
                :disabled="!canForbid"
                class="text-[13px]"
                @click="handleActiveUser(0)"
              >
                禁用
              </n-button>
              <n-button
                type="tertiary"
                :disabled="!canActive"
                class="text-[13px]"
                @click="handleActiveUser(1)"
              >
                启用
              </n-button>
              <n-button
                type="tertiary"
                :disabled="!checkedRowKeys.length"
                class="text-[13px]"
                @click="handleDelUser"
              >
                删除
              </n-button>
            </n-button-group>
          </n-space>
          <wp-data-table
            v-loading="loading"
            :data="data"
            :checked-row-keys="checkedRowKeys"
            :columns="columns"
            @page-change="handlePageChange"
            @item-click="handleItemClick"
            @select-change="handleSelectChange"
            :pages="pageResultInfo.pages"
            :total="pageResultInfo.total"
            :is-sort="false"
            :on-contextmenu="userContextMenuProps"
            :only-check-all="true"
          >
          </wp-data-table>
          <n-dropdown
            placement="bottom-start"
            trigger="manual"
            :x="userDropDown.x"
            :y="userDropDown.y"
            :options="userDropDown.options"
            :show="userDropDown.showDropdown"
            :on-clickoutside="handleUserDropClickOutside"
            @select="handleUserDropSelect"
            size="small"
            :render-label="renderAllActionsLabel"
          />
        </div>
      </template>
    </n-split>

    <!-- 添加或者更新用户 -->
    <my-dialog
      v-if="dialogs.addAndUpdateUser"
      @close="dialogs.addAndUpdateUser = false"
      default-width="768px"
      default-height="90%"
    >
      <template #title>
        <div class="text-[13px] flex items-center">用户信息</div>
      </template>
      <CreateAndUpdateUser
        class="mt-2"
        :rootDep="rootDep"
        :user-res="curUser"
        :is-modify="editModels.user === 'update'"
        @change-user="handleAddAndUpdateUser"
        @visible-change="(value) => (dialogs.addAndUpdateUser = value)"
      ></CreateAndUpdateUser>
    </my-dialog>

    <!-- 添加或者更新部门 -->
    <my-dialog
      v-if="dialogs.addAndUpdateDep"
      @close="dialogs.addAndUpdateDep = false"
      default-width="768px"
      default-height="60%"
    >
      <template #title>
        <div class="text-[13px] flex items-center">部门信息</div>
      </template>
      <CreateAndUpdateDep
        class="mt-2"
        :is-modify="editModels.dep === 'update'"
        :dep-res="curDep"
        :delDep="delDep"
        :rootDep="rootDep"
        @visible-change="(value) => (dialogs.addAndUpdateDep = value)"
        @change-dep="handleAddAndUpdateDep"
      ></CreateAndUpdateDep>
    </my-dialog>

    <!-- 批量设置用户系统角色 -->
    <my-dialog
      v-if="dialogs.setUserRole"
      @close="dialogs.setUserRole = false"
      default-width="540px"
      default-height="30%"
    >
      <template #title>
        <div class="text-[13px] flex items-center">用户角色</div>
      </template>
      <SetUserSystemRole
        class="mt-2"
        :rootDepId="rootDep.id"
        :check-user-ids="selectUserIds"
        @visible-change="(value) => (dialogs.setUserRole = value)"
        @set-user-role="handleSetUserRole"
      ></SetUserSystemRole>
    </my-dialog>

    <!-- 批量设置用户个人空间大小 -->
    <my-dialog
      v-if="dialogs.setUserSizeMax"
      @close="dialogs.setUserSizeMax = false"
      default-width="540px"
      default-height="30%"
    >
      <template #title>
        <div class="text-[13px] flex items-center">个人空间大小</div>
      </template>
      <SetUserSizeMax
        class="mt-2"
        :rootDepId="rootDep.id"
        :check-user-ids="selectUserIds"
        @visible-change="(value) => (dialogs.setUserSizeMax = value)"
        @set-user-size-max="handleSetUserSizeMax"
      ></SetUserSizeMax>
    </my-dialog>

    <!-- 添加用户到部门 -->
    <my-dialog
      v-if="dialogs.addUserToDep"
      @close="dialogs.addUserToDep = false"
      default-width="768px"
      default-height="50%"
    >
      <template #title>
        <div class="text-[13px] flex items-center">添加到部门</div>
      </template>
      <AddUserToDep
        class="mt-2"
        :rootDep="rootDep"
        :check-user-ids="selectUserIds"
        @visible-change="(value) => (dialogs.addUserToDep = value)"
        @add-user-to-dep="handleAddUserToDep"
      ></AddUserToDep>
    </my-dialog>

    <!-- 迁移用户到部门 -->
    <my-dialog
      v-if="dialogs.moveUserToDep"
      @close="dialogs.moveUserToDep = false"
      default-width="540px"
      default-height="30%"
    >
      <template #title>
        <div class="text-[13px] flex items-center">迁移到部门</div>
      </template>
      <MoveUserToDep
        class="mt-2"
        :rootDep="rootDep"
        :check-user-ids="selectUserIds"
        :check-user-dep-ids="selectUserDepIds"
        @visible-change="(value) => (dialogs.moveUserToDep = value)"
        @move-user-to-dep="handleMoveUserToDep"
      ></MoveUserToDep>
    </my-dialog>

    <!-- 批量设置部门空间大小 -->
    <my-dialog
      v-if="dialogs.setDepSizeMax"
      @close="dialogs.setDepSizeMax = false"
      default-width="540px"
      default-height="30%"
    >
      <template #title>
        <div class="text-[13px] flex items-center">批量设置空间大小</div>
      </template>
      <SetDepSizeMax
        class="mt-2"
        :rootDep="rootDep"
        :check-dep-ids="delDep.id ? [delDep.id] : []"
        @visible-change="(value) => (dialogs.setDepSizeMax = value)"
        @set-dep-size-max="handleSetDepSizeMax"
      ></SetDepSizeMax>
    </my-dialog>

    <!-- 进入部门目录 -->
    <MyDialog
      default-width="90%"
      default-height="90%"
      v-if="dialogs.explorer"
      @close="dialogs.explorer = false"
    >
      <template #title>
        <div class="flex items-center text-[#555] text-[13px]">个人空间</div>
      </template>
      <Explorer></Explorer>
    </MyDialog>
  </div>
</template>

<script setup lang="ts">
import type { VNodeChild } from 'vue'
import { useMessage, useDialog } from 'naive-ui'
import type {
  TreeOverrideNodeClickBehavior,
  TreeOption,
  DataTableColumns,
  DataTableColumn,
  TreeDropInfo
} from 'naive-ui'
import useUserStore from '@/stores/modules/user'
import useRoleStore from '@/stores/modules/role'
import useDepStore from '@/stores/modules/department'
import useSettingStore from '@/stores/modules/settings'
import {
  createDepartment,
  delDepartment,
  getDepartmentByPage,
  getUserDepartmentByPage,
  setSizeMaxDepartment,
  sortDepartment,
  updateDepartment
} from '@/api/department'
import {
  delUser,
  getUsers,
  setUserRole,
  setUserSizeMax,
  setUserStatus
} from '@/api/user'
import {
  createUserDep,
  removeUserDep,
  updateUserDep,
  copyUserDep,
  moveUserDep
} from '@/api/userDep'
import type {
  UserNotDepRes,
  UserReq,
  UserUpdateReq,
  UserCreateReq,
  SetUserRoleReq,
  SetUserSizeMaxReq
} from '@/types/user'
import type {
  DepartmentUpdateReq,
  DepartmentCreateReq,
  DepartmentSetSizeMax
} from '@/types/department'
import type { UserDepCopyReq, UserDepMoveReq } from '@/types/userDep'
import { PERMISSIONS } from '@/constants/permission'
import { userMenuShow } from '@/hooks/useMenuShow'
import { load } from '@/utils/loading'
import { convertFromBytes } from '@/utils/index'
import {
  renderAvatorSrc,
  renderDepLabel,
  renderDropLabel
} from '@/utils/commonBusiness'
import SvgIcon from '@/components/SvgIcon/index.vue'
import PicValidCode from '@/components/PicValidCode/index.vue'
import CreateAndUpdateUser from './components/CreateAndUpdateUser.vue'
import CreateAndUpdateDep from './components/CreateAndUpdateDep.vue'
import SetUserSystemRole from './components/SetUserSystemRole.vue'
import SetDepSizeMax from './components/SetDepSizeMax.vue'
import SetUserSizeMax from './components/SetUserSizeMax.vue'
import AddUserToDep from './components/AddUserToDep.vue'
import MoveUserToDep from './components/MoveUserToDep.vue'
import type { IndexObj } from '@/types/commom'
import Explorer from '@/views/User/Explorer/index.vue'
import { events } from '@/utils/bus'
import { navTypeList } from '@/constants/explorer'

const userStore = useUserStore()
const roleStore = useRoleStore()
const depStore = useDepStore()
const settingStore = useSettingStore()
const message = useMessage()
const dialog = useDialog()
const { isSmall } = userMenuShow()

// 左边的蒙层遮罩
const showLeftMask = ref(false)
const hanldeSplitSizeChange = (size: number) => {
  if (size !== 0) {
    settingStore.setDepSplitSize(size)
  }
}

const handleShowMask = () => {
  showLeftMask.value = !showLeftMask.value
}

// ======================================== 部门和用户管理=====================================================
const editModels = reactive({
  dep: 'create',
  user: 'create'
})

// ========================================= 部门的相关操作 =================================================
const override: TreeOverrideNodeClickBehavior = ({ option }) => {
  return 'default'
}

const options = ref<IndexObj[]>([])

const depNameSearch = ref('')

// 有children进行加载
const handleLoad = (option: TreeOption) => {
  return new Promise<void>((resolve) => {
    // 加载部门下的用户，加载部门下的子部门
    Promise.all([
      getUserDepartmentByPage({
        page: 1,
        pageSize: 999,
        pid: option.id as string
      })
    ])
      .then(([res1]) => {
        const newDeps = res1.data.items.map((item) => {
          return {
            ...item,
            key: item.id,
            label: item.name,
            isLeaf: !!item.isLeaf,
            isDep: true
          }
        })

        option.children = [...newDeps]
        if (!option.children.length) {
          option.isLeaf = true
        }
      })
      .finally(() => {
        resolve()
      })
  })
}

const renderLabel = ({ option }: { option: TreeOption }): VNodeChild => {
  return renderDepLabel(option)
}

// 加载根部门数组
const initOptions = () => {
  // const res = await getDepartmentByPage({ page: 1, pageSize: 999, pid: '-1' })
  // options.value = res.data.items.map((item) => {
  //   return {
  //     ...item,
  //     label: item.name,
  //     key: item.id,
  //     isLeaf: false
  //   }
  // })
  // 这里应该根据用户的权限定义，用户为部门管理员（有部门列表查看的权限），查询用户所在的部门
  options.value = [{ id: '1', label: '全部部门', key: '-1', isLeaf: false }]
}

// 部门项右键菜单
const baseDepOptions: IndexObj[] = [
  {
    label: '编辑',
    key: 'dep-edit',
    myIcon: 'bianji',
    auth: {
      role: [PERMISSIONS.DEP_EDIT]
    }
  },
  {
    label: '删除',
    key: 'dep-del',
    myIcon: 'chacha1',
    auth: {
      role: [PERMISSIONS.DEP_EDIT]
    }
  },
  {
    type: 'divider',
    key: 'd1'
  },
  {
    label: '新建用户',
    key: 'dep-add-user',
    myIcon: 'tianjiayonghu',
    auth: {
      role: [PERMISSIONS.USER_EDIT]
    }
  },
  {
    label: '设置部门管理员',
    key: 'dep-set-admin',
    myIcon: 'tianjiayonghu',
    auth: {
      role: [PERMISSIONS.ADMIN_MEMBER_AUTH_MANAGE]
    }
  },
  {
    type: 'divider',
    key: 'd2'
  },
  {
    label: '添加子部门',
    key: 'dep-add-sub',
    myIcon: 'zengjiatianjiajiahao',
    auth: {
      role: [PERMISSIONS.DEP_EDIT]
    }
  },
  {
    type: 'divider',
    key: 'd3'
  },
  {
    label: '刷新',
    key: 'dep-reflesh',
    myIcon: 'shuaxin2'
  },
  {
    label: '批量设置空间大小',
    key: 'dep-set-size',
    myIcon: 'cunchu',
    auth: {
      role: [PERMISSIONS.DEP_EDIT]
    }
  }
]

const depDropDown = reactive<IndexObj>({
  showDropdown: false,
  options: baseDepOptions,
  x: 0,
  y: 0
})

const handleDepDropSelect = (key: string) => {
  if (key === 'dep-del') {
    handleDelDep([delDep.value.id])
  } else if (key === 'dep-edit') {
    curDep.value = delDep.value
    handleToModifyDep()
  } else if (key === 'dep-add-sub') {
    handleToAddDep()
  } else if (key === 'dep-add-user') {
    handleToAddUser()
  } else if (key === 'dep-set-size') {
    handleToSetDepSizeMax()
  }
  depDropDown.showDropdown = false
}
const handleDepClickoutside = () => {
  depDropDown.showDropdown = false
}

// 部门项被点击，加载用户
const nodeProps = ({ option }: { option: TreeOption }) => {
  return {
    onClick() {
      showLeftMask.value = false
      curDep.value = option
      delDep.value = option
      pageInfo.depId =
        (option.id as string) === '1' ? undefined : (option.id as string)
      loadUsers()
    },
    onContextmenu(e: MouseEvent): void {
      if (option.id === '1') {
        depDropDown.options = depDropDown.options.filter((item: IndexObj) => {
          return !['dep-edit', 'dep-del', 'd1'].includes(item.key)
        })
      } else {
        baseDepOptions[1].disabled = !option.isLeaf
        depDropDown.options = baseDepOptions
      }
      delDep.value = option
      depDropDown.showDropdown = true
      depDropDown.x = e.clientX
      depDropDown.y = e.clientY
      e.preventDefault()
    }
  }
}

// 部门项目拖拽排序
const handleAllowDrop = (info: {
  dropPosition: 'before' | 'after' | 'inside'
  node: TreeOption
  phase: 'drag' | 'drop'
}) => {
  return true
}

// 拖拽排序和迁移
const handleDrop = ({ node, dragNode, dropPosition }: TreeDropInfo) => {
  if (dropPosition === 'after') {
    // dragNode停留在node的后方
    handleSortDep([node.id as string, dragNode.id as string])
  } else if (dropPosition === 'before') {
    // dragNode停留在node的前方
    handleSortDep([dragNode.id as string, node.id as string])
  } else if (dropPosition === 'inside') {
    // 停留在里面，进行父部门的迁移
    // node即为父亲
    // console.log('inside')
    handleUpdateDep({
      depId: dragNode.id as string,
      name: dragNode.name as string,
      pid: node.id as string,
      sizeMax: dragNode.sizeMax as string,
      cooperatDepIds: (dragNode.copDepartments as IndexObj[]).map(
        (item: IndexObj) => item.linkDepId
      ) as string[]
    })
  }

  // console.log(node, dragNode, dropPosition)
}

const handleSortDep = (ids: string[]) => {
  sortDepartment(ids)
    .then(() => {
      afterDepAction()
    })
    .catch(console.error)
}

onMounted(() => {
  initOptions()
})

// =================================== 右侧加载用户信息==============================
const userNameSerach = ref('')
const loading = ref(false)
const data = ref<UserNotDepRes[]>([])

const pageInfo = reactive<UserReq>({
  page: 1,
  pageSize: 50,
  username: '',
  depId: undefined
})

const pageResultInfo = reactive({
  pages: 0,
  total: 0
})

// 进入用户目录
const handleEnterFolder = () => {
  // 打开explorer对话框
  dialogs.explorer = true
  console.log(curDep.value)

  setTimeout(() => {
    // 文件夹处理
    events.emit('node-click', {
      nav: {
        key: curDep.value!.Sources[0].id,
        label: curDep.value!.name,
        myType: navTypeList.SOURCE
      }
    })
  }, 300)
}

const createColumns = (): DataTableColumns<UserNotDepRes> => {
  const selectColumn: DataTableColumn<UserNotDepRes> = {
    type: 'selection',
    minWidth: 30,
    width: 30,
    disabled(row: IndexObj) {
      return row.id === '1740385704448253953'
    }
  }

  const staticColumns: DataTableColumns<UserNotDepRes> = [
    {
      title: '昵称/账号',
      key: 'username',
      minWidth: 120,
      width: 120,
      render: (row) =>
        h(
          'div',
          {
            style: {
              display: 'flex',
              alignItems: 'center',
              fontSize: '13px',
              opacity: row.isActive ? '1' : '.4'
            }
          },
          [
            h(NAvatar, {
              round: true,
              size: 16,
              color: 'rgba(255,255,255,1)',
              src: renderAvatorSrc(row.avator, row.username),
              class: 'mr-1'
            }),
            h(
              NButton,
              {
                type: 'primary',
                text: true,
                onClick: (e: MouseEvent) => handleToModifyUser2(e, row),
                class: 'text-[13px]'
              },
              {
                default: () => {
                  return `${row.username || row.nickname}`
                }
              }
            )
          ]
        )
    },
    {
      title: '角色权限',
      key: 'roleId',
      minWidth: 120,
      width: 120,
      render: (row) => {
        const role = roleStore.systemRoles.find((item) => {
          return item.id === row.roleId
        })
        return h(
          'div',
          {
            style: {
              display: 'flex',
              alignItems: 'center',
              fontSize: '13px',
              opacity: row.isActive ? '1' : '.4'
            }
          },
          [
            role
              ? h(
                  'div',
                  {
                    style: {
                      display: 'flex',
                      alignItems: 'center',
                      fontSize: '13px'
                    }
                  },

                  [
                    h(SvgIcon, {
                      icon: 'yuandian-copy',
                      color: role.label,
                      size: '24px'
                    }),
                    role.name as string
                  ]
                )
              : ''
          ]
        )
      }
    },
    {
      title: '空间大小',
      key: 'sizeMax',
      minWidth: 120,
      width: 120,
      render(row) {
        const sizeMax = convertFromBytes(row.sizeMax)
        return `${convertFromBytes(row.sizeUse)}/ ${
          sizeMax === '0B' ? '无限制' : sizeMax
        }`
      }
    },
    {
      title: '所在部门',
      key: 'dep',
      minWidth: 200,
      width: 200,
      render: (row) => {
        const tags = row.Departments.map((item) => {
          const authRole = roleStore.docRoles.find(
            (item2) => item2.id === item.UserDepartment.roleId
          )
          return h(
            NTag,
            {
              round: true,
              style: {
                alignItems: 'center',
                fontSize: '13px',
                marginRight: '8px',
                marginBottom: '8px'
              }
            },
            {
              default: () => {
                return [
                  h(SvgIcon, {
                    icon: 'yuandian-copy',
                    color: (authRole && authRole.label) || '',
                    size: '24px'
                  }),
                  item.name as string
                ]
              }
            }
          )
        })

        return h(
          'div',
          {
            style: {
              display: 'flex',
              alignItems: 'center',
              flexWrap: 'wrap',
              fontSize: '13px',
              opacity: row.isActive ? '1' : '.4'
            }
          },
          tags
        )
      }
    }
  ]

  if (
    userStore.permissions?.some((item) => {
      return item === PERMISSIONS.USER_EDIT
    })
  ) {
    staticColumns.unshift(selectColumn)
  }

  return staticColumns
}

const checkedRowKeys = ref<UserNotDepRes[]>([])

// 用户关键字搜索
const handleKeyUp = (e: KeyboardEvent) => {
  if (e.key === 'Enter') {
    loadUsers()
  }
}

// 可启用用户按钮
const canActive = computed(() => {
  if (checkedRowKeys.value.length === 1) {
    if (checkedRowKeys.value[0].isActive) {
      return false
    }
    return true
  }

  if (!checkedRowKeys.value.length) {
    return false
  }

  return true
})
// 可禁用用户按钮
const canForbid = computed(() => {
  if (checkedRowKeys.value.length === 1) {
    if (checkedRowKeys.value[0].isActive) {
      return true
    }
    return false
  }

  if (!checkedRowKeys.value.length) {
    return false
  }

  return true
})

watch(
  checkedRowKeys,
  (newValue) => {
    // 存在一个length为0的则forbid
    const res = checkedRowKeys.value.some((item) => {
      return !item.Departments.length
    })
    allActions.value[4].disabled = res

    const drop = userDropDown.options.find(
      (item: IndexObj) => item.key === 'user-more'
    )
    drop.children[1].disabled = res
  },
  {
    deep: true
  }
)

const columns = createColumns()
const userDropDown = reactive<IndexObj>({
  showDropdown: false,
  options: [
    {
      label: '编辑',
      key: 'user-edit',
      myIcon: 'chanpinfenlei-bianjiyonghu',
      disabled: checkedRowKeys.value.length !== 1
    },
    {
      type: 'divider',
      key: 'd3'
    },
    {
      label: '禁用',
      key: 'user-forbid',
      myIcon: 'jianshaojianqujianhao'
    },
    {
      label: '启用',
      key: 'user-active',
      myIcon: 'gougou'
    },
    {
      label: '删除',
      key: 'user-del',
      myIcon: 'shanchuyonghu'
    },
    {
      label: '角色权限设置',
      key: 'user-set-role',
      myIcon: 'tianjiayonghu'
    },
    {
      type: 'divider',
      key: 'd2'
    },
    {
      label: '从部门中移除',
      key: 'user-del-from-dep',
      myIcon: 'jianshaojianqujianhao'
    },
    {
      label: '添加到部门',
      key: 'user-add-to-dep',
      myIcon: 'zengjiatianjiajiahao'
    },
    {
      type: 'divider',
      key: 'd1'
    },
    {
      label: '更多',
      key: 'user-more',
      myIcon: 'gengduo1',
      children: [
        {
          label: '空间大小设置',
          key: 'user-set-size',
          myIcon: 'cunchu'
        },
        {
          label: '迁移到部门',
          key: 'user-move-dep',
          myIcon: 'transmission'
        },
        {
          label: '部门权限复制',
          key: 'user-auth-copy',
          myIcon: 'fuzhi1',
          disabled: true
        },
        {
          label: '部门权限粘贴',
          key: 'user-copy-paste',
          myIcon: 'niantie',
          disabled: true
        }
      ]
    }
  ],
  x: 0,
  y: 0
})
const handleUserDropClickOutside = () => {
  userDropDown.showDropdown = false
}

const handleUserDropSelect = (key: string) => {
  userDropDown.showDropdown = false
  if (key === 'user-edit') {
    handleToModifyUser()
  } else if (key === 'user-forbid') {
    handleActiveUser(0)
  } else if (key === 'user-active') {
    handleActiveUser(1)
  } else if (key === 'user-del') {
    handleDelUser()
  } else if (key === 'user-del-from-dep') {
    handleRemoveUserFromDep()
  } else if (key === 'user-set-role') {
    handleToSetUserRole()
  } else if (key === 'user-set-size') {
    handleToSetUserSizeMax()
  } else if (key === 'user-add-to-dep') {
    handleToAddUserToDep()
  } else if (key === 'user-move-dep') {
    handleToMoveUserToDep()
  }
}

const userContextMenuProps = (row: UserNotDepRes) => {
  return (e: MouseEvent) => {
    if (row.id === userStore.userInfo!.id) {
      return
    }

    if (!checkedRowKeys.value.find((item) => item.id === row.id)) {
      checkedRowKeys.value.push(row)
    }
    e.preventDefault()
    userDropDown.showDropdown = false
    userDropDown.options[0].disabled = checkedRowKeys.value.length !== 1
    nextTick().then(() => {
      userDropDown.showDropdown = true
      userDropDown.x = e.clientX
      userDropDown.y = e.clientY
    })
  }
}

const userActions = ref([
  {
    label: '批量添加',
    key: 'user.buckAdd'
  }
])

const handleItemClick = (row: UserNotDepRes) => {
  if (row.id === userStore.userInfo!.id) {
    return
  }
  !checkedRowKeys.value.some((item) => item.id === row.id)
    ? checkedRowKeys.value.push(row)
    : (checkedRowKeys.value = checkedRowKeys.value.filter(
        (item) => item.id !== row.id
      ))
}

const handleSelectChange = (keys: string[], rows: UserNotDepRes[]) => {
  console.log(rows)

  checkedRowKeys.value = rows.filter(
    (item) => item.id !== userStore.userInfo!.id
  )
}

const handleBuckSelect = () => {}

const allActions = ref<IndexObj[]>([
  {
    label: '角色权限设置',
    key: 'role',
    myIcon: 'jiaosequanxian1'
  },
  {
    label: '空间大小设置',
    key: 'sizeMax',
    myIcon: 'cunchu'
  },
  {
    label: '从部门中移除',
    key: 'dep.removeFrom',
    myIcon: 'jianshaojianqujianhao'
  },
  {
    label: '添加到部门',
    key: 'dep.addTo',
    myIcon: 'zengjiatianjiajiahao'
  },
  {
    label: '迁移到部门',
    key: 'dep.moveTo',
    myIcon: 'transmission',
    disabled: false
  }
])

const renderAllActionsLabel = (option: IndexObj) => {
  return renderDropLabel(
    option.myIcon,
    option.label,
    undefined,
    '13px',
    '#13b1fe'
  )
}

// 选中用户的批量操作
const handleAllBuckSelect = (key: string) => {
  if (!checkedRowKeys.value.length) {
    return message.warning('请至少选中一个用户')
  }
  if (key === 'role') {
    handleToSetUserRole()
  } else if (key === 'sizeMax') {
    handleToSetUserSizeMax()
  } else if (key === 'dep.removeFrom') {
    handleRemoveUserFromDep()
  } else if (key === 'dep.addTo') {
    handleToAddUserToDep()
  } else if (key === 'dep.moveTo') {
    handleToMoveUserToDep()
  }
}

// 获取用户列表
const loadUsers = () => {
  loading.value = true
  pageInfo.username = userNameSerach.value
  getUsers(pageInfo)
    .then((res) => {
      data.value = res.data.items
      pageResultInfo.pages = res.data.pages
      pageResultInfo.total = res.data.total
    })
    .catch(console.error)
    .finally(() => {
      loading.value = false
      checkedRowKeys.value = []
    })
}

const handlePageChange = (page?: number, pageSize?: number) => {
  page && (pageInfo.page = page)
  pageSize && (pageInfo.pageSize = pageSize)
  loadUsers()
}

onMounted(async () => {
  if (!roleStore.roleList.length) {
    await roleStore.getRoleList()
  }
  loadUsers()
})

// ===================================用户相关的操作=================================
const dialogs = reactive({
  addAndUpdateUser: false,
  addAndUpdateDep: false,
  setUserRole: false,
  setDepSizeMax: false,
  setUserSizeMax: false,
  addUserToDep: false,
  moveUserToDep: false,
  explorer: false
})

const handleToAddUser = () => {
  dialogs.addAndUpdateUser = true
  editModels.user = 'create'
}

const curUser = ref()
const handleToModifyUser = () => {
  curUser.value = checkedRowKeys.value[0]
  editModels.user = 'update'
  dialogs.addAndUpdateUser = true
}

const handleToModifyUser2 = (e: any, row: UserNotDepRes) => {
  if (row.id === userStore.userInfo!.id) {
    return
  }
  e && e.stopPropagation()
  curUser.value = row
  editModels.user = 'update'
  dialogs.addAndUpdateUser = true
}

// 将用户从当前部门中移除
const handleRemoveUserFromDep = () => {
  if (!curDep.value || curDep.value.id === '1') {
    message.warning('处于根部门，无法移除')
    return
  }

  const checkUsers = checkedRowKeys.value

  // 查询出这些用户的userDepId
  const userDepIds = checkUsers.map((item) => {
    return item.Departments.filter((item2) => {
      return item2.id === curDep.value.id
    }).map((item3) => {
      return item3.UserDepartment.id
    })[0]
  })

  dialog.warning({
    title: '提示',
    content: '你确定要将这些用户从当前部门移除吗?',
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: () => {
      load.show()
      removeUserDep(userDepIds)
        .then(() => {
          message.success('用户从当前部门移除成功')
          afterUserAction()
        })
        .catch(console.error)
        .finally(() => {
          load.hide()
        })
    },
    onNegativeClick: () => {}
  })
}

// 批量设置用户的系统角色
const computeSelectUserIds = () => {
  selectUserIds.value = checkedRowKeys.value.map((item) => {
    return item.id
  })
}

const selectUserIds = ref<string[]>([])
const selectUserDepIds = ref<string[]>([])
const handleToSetUserRole = () => {
  computeSelectUserIds()
  dialogs.setUserRole = true
}

const handleSetUserRole = (data: SetUserRoleReq) => {
  load.show()
  setUserRole(data)
    .then(() => {
      message.success('设置用户系统角色成功')
      dialogs.setUserRole = false
      afterOpt()
    })
    .catch(console.error)
    .finally(() => {
      load.hide()
    })
}

// 批量设置用户的个人空间大小
const handleToSetUserSizeMax = () => {
  computeSelectUserIds()
  dialogs.setUserSizeMax = true
}

const handleSetUserSizeMax = (data: SetUserSizeMaxReq) => {
  load.show()
  setUserSizeMax(data)
    .then(() => {
      message.success('设置用户个人空间大小成功')
      dialogs.setUserSizeMax = false
      afterOpt()
    })
    .catch(console.error)
    .finally(() => {
      load.hide()
    })
}

// 添加用户到部门
const handleToAddUserToDep = () => {
  computeSelectUserIds()
  dialogs.addUserToDep = true
}

const handleAddUserToDep = (data: UserDepCopyReq) => {
  load.show()
  copyUserDep(data)
    .then(() => {
      message.success('用户添加到部门成功')
      dialogs.addUserToDep = false
      afterOpt()
    })
    .catch(console.error)
    .finally(() => {
      load.hide()
    })
}

// 迁移用户到部门
const handleToMoveUserToDep = () => {
  computeSelectUserIds()
  dialogs.moveUserToDep = true
}

const handleMoveUserToDep = (data: UserDepMoveReq) => {
  load.show()
  moveUserDep({
    ...data,
    curDepId: curDep.value.id
  })
    .then(() => {
      message.success('用户迁移到部门成功')
      dialogs.moveUserToDep = false
      afterOpt()
    })
    .catch(console.error)
    .finally(() => {
      load.hide()
    })
}

// 用户操作完成后的处理函数
const afterOpt = () => {
  checkedRowKeys.value = []
  loadUsers()
}

const afterUserAction = () => {
  dialogs.addAndUpdateUser = false
  editModels.user = 'create'
  checkedRowKeys.value = []
  loadUsers()
}

// 激活用户账户
const handleActiveUser = (status: number) => {
  load.show()
  setUserStatus({
    userIds: checkedRowKeys.value.map((item) => item.id),
    status
  })
    .then(() => {
      message.success('操作成功')
      afterOpt()
    })
    .catch(console.error)
    .finally(() => {
      load.hide()
    })
}

// 删除用户
const handleDelUser = () => {
  let dialogObj = dialog.warning({
    title: '你确定要删除这些用户吗？',
    class: '!w-[768px]',
    content: () =>
      h(
        PicValidCode,
        {
          showCloseIcon: false,
          class: '!w-full',
          onOnFinish: (picCode: string) => {
            load.show()
            delUser(
              checkedRowKeys.value.map((item) => item.id),
              picCode
            )
              .then(() => {
                message.success('删除用户成功')
                afterOpt()
                dialogObj.destroy()
              })
              .catch(console.error)
              .finally(() => {
                load.hide()
              })
          }
        },
        []
      )
  })
}

// 添加用户
const handleAddUser = (data: UserCreateReq) => {
  load.show()
  createUserDep(data)
    .then(() => {
      message.success('添加用户成功')
      afterUserAction()
    })
    .catch(console.error)
    .finally(() => {
      load.hide()
    })
}

// 更新用户
const handleUpdateUser = (data: UserUpdateReq) => {
  load.show()
  updateUserDep(data)
    .then(() => {
      message.success('更新用户成功')
      afterUserAction()
    })
    .catch(console.error)
    .finally(() => {
      load.hide()
    })
}

const handleAddAndUpdateUser = (type: number, data: UserUpdateReq) => {
  if (type === 1) {
    handleUpdateUser(data)
  } else {
    handleAddUser(data)
  }
}

// ================================================== 部门的相关操作 ======================================================

// 根据用户的不同获取的不同的根部门
const rootDep = ref<IndexObj>({
  id: '1',
  label: '全部部门',
  key: '-1',
  isLeaf: false,
  pid: '-1'
})

const curDep = ref<any>({
  id: '1',
  label: '全部部门',
  key: '-1',
  isLeaf: false,
  pid: '-1'
})

const handleToAddDep = () => {
  dialogs.addAndUpdateDep = true
  editModels.dep = 'create'
}

const handleToModifyDep = () => {
  if (curDep.value.id === '1') {
    return
  }
  editModels.dep = 'update'
  dialogs.addAndUpdateDep = true
}

const delDep = ref<IndexObj>({})

// 删除部门
const handleDelDep = (ids: string[]) => {
  let dialogObj = dialog.warning({
    title: '你确定要删除这些部门吗？',
    class: '!w-[768px]',
    content: () =>
      h(
        PicValidCode,
        {
          showCloseIcon: false,
          class: '!w-full',
          onOnFinish: (picCode: string) => {
            load.show()
            delDepartment(ids, picCode)
              .then(() => {
                message.success('删除部门成功')
                afterDepAction()
                dialogObj.destroy()
              })
              .catch(console.error)
              .finally(() => {
                load.hide()
              })
          }
        },
        []
      )
  })
}

// 添加部门
const handleAddDep = (data: DepartmentCreateReq) => {
  load.show()
  createDepartment(data)
    .then(() => {
      message.success('添加部门成功')
      afterDepAction()
    })
    .catch(console.error)
    .finally(() => {
      load.hide()
    })
}

// 批量设置部门空间大小
const handleToSetDepSizeMax = () => {
  dialogs.setDepSizeMax = true
}

const handleSetDepSizeMax = (data: DepartmentSetSizeMax) => {
  load.show()
  setSizeMaxDepartment(data)
    .then(() => {
      message.success('设置部门空间容量大小成功')
      afterDepAction()
      dialogs.setDepSizeMax = false
    })
    .catch(console.error)
    .finally(() => {
      load.hide()
    })
}

// 更新部门
const handleUpdateDep = (data: DepartmentUpdateReq) => {
  load.show()
  updateDepartment(data)
    .then(() => {
      message.success('更新部门成功')
      afterDepAction()
    })
    .catch(console.error)
    .finally(() => {
      load.hide()
    })
}

const handleAddAndUpdateDep = (type: number, data: DepartmentUpdateReq) => {
  if (type === 1) {
    handleUpdateDep(data)
  } else {
    handleAddDep(data)
  }
}

// 部门操作后的处理函数
const afterDepAction = () => {
  dialogs.addAndUpdateDep = false
  editModels.dep = 'create'
  initOptions()
  // store里面的部门也进行更新
  depStore.getFullDepList()
}
</script>

<style scoped lang="scss">
.user-con {
  // font-size: 13px;
  :deep(.n-tag__content) {
    display: flex;
    align-items: center;
  }

  :deep(.n-split .n-split-pane-2) {
    overflow: auto;
  }

  :deep(.n-data-table-tbody .n-data-table-tr:hover .n-data-table-td) {
    background-color: #e5f3ff;
  }
}
</style>
